-- StoryEngine.lua - 基于设计方案的Defold兼容故事引擎
-- 重构为独立模块，不使用面向对象设计

-- 引用Defold模块
local gui = require("gui")

-- 引擎状态
local state = {
    nodes = {},              -- 故事节点表
    variables = {},          -- 游戏变量
    current_node = nil,      -- 当前节点ID
    save_file = "savegame.json",
    gui_script = nil         -- GUI脚本引用，用于更新UI
}

-- 模块表
local M = {}

-- 初始化函数
function M.init(gui_script)
    state.gui_script = gui_script
    state.nodes = {}
    state.variables = {}
    state.current_node = nil
    state.save_file = "savegame.json"
    state.game_over = false
    state.score = 0
    state.ending = ""
    state.history = {}
    state.choices = {}
end

-- 设置GUI脚本引用
function M.set_gui_script(gui_script)
    state.gui_script = gui_script
end

-- 添加故事节点
function M.add_node(node)
    if not node.id then
        error("节点必须包含id字段")
    end
    
    state.nodes[node.id] = node
    print("已添加节点: " .. node.id)
end

-- 加载故事文件
function M.load_story(filename)
    -- 使用 require 加载模块
    print("尝试加载故事文件: " .. filename)
    
    -- 尝试不同的加载方式
    local success, story_data
    
    -- 方法1：直接使用 require
    success, story_data = pcall(require, filename)
    
    if not success then
        -- 方法2：尝试将点号转换为路径
        local path = filename:gsub("%.", "/")
        success, story_data = pcall(require, path)
    end
    
    if not success then
        -- 方法3：尝试添加 .lua 后缀
        local path_with_ext = filename:gsub("%.", "/") .. ".lua"
        success, story_data = pcall(require, path_with_ext)
    end
    
    if not success then
        -- 方法4：尝试使用 dofile 直接加载文件
        local path = filename:gsub("%.", "/") .. ".lua"
        success, story_data = pcall(dofile, path)
    end
    
    if not success then
        -- 方法5：在Defold环境中尝试使用 sys.load_resource
        if sys and sys.load_resource then
            -- 尝试多种路径格式，使用绝对路径
            local paths_to_try = {
                "/game/XianxiaStory.lua",  -- 修仙游戏绝对路径
                "/game/XianxiaStory",      -- 不带.lua后缀
                "/src/game/XianxiaStory.lua",  -- 源代码路径
            }
            
            for _, resource_path in ipairs(paths_to_try) do
                print("尝试加载资源: " .. resource_path)
                local resource_data = sys.load_resource(resource_path)
                if resource_data then
                    -- 使用 loadstring 加载资源内容
                    local load_func, load_err = loadstring(resource_data)
                    if load_func then
                        success, story_data = pcall(load_func)
                        if success then
                            print("成功加载资源: " .. resource_path)
                            break
                        else
                            print("执行资源内容失败: " .. tostring(story_data))
                        end
                    else
                        print("加载资源内容失败: " .. load_err)
                    end
                else
                    print("无法加载资源: " .. resource_path)
                end
            end
        end
    end
    
    if success then
        -- 如果加载成功，添加节点
        for _, node in ipairs(story_data) do
            M.add_node(node)
        end
        print("已加载 " .. #story_data .. " 个故事节点")
    else
        print("加载故事文件失败: " .. tostring(story_data))
        error(story_data)
    end
end

-- 开始游戏
function M.start_game(start_node_id)
    if not state.nodes[start_node_id] then
        error("找不到起始节点: " .. start_node_id)
    end
    
    state.current_node = start_node_id
    
    -- 添加延迟确保GUI完全初始化后再显示节点
    timer.delay(0.1, false, function()
        M.show_node(start_node_id)
        print("StoryEngine: 游戏已开始，节点 " .. start_node_id)
    end)
end

-- 显示节点内容
-- 显示指定的节点
function M.show_node(node_id)
    print("StoryEngine: ========== show_node 开始 ==========")
    print("StoryEngine: 显示节点 " .. node_id)
    
    -- 查找节点
    local node = state.nodes[node_id]
    if not node then
        print("StoryEngine: 错误：找不到节点 " .. node_id)
        print("StoryEngine: 所有可用节点:")
        for node_id, _ in pairs(state.nodes) do
            print("StoryEngine: - " .. node_id)
        end
        return false
    end
    
    print("StoryEngine: 找到节点: " .. node.id .. "，标题: " .. tostring(node.title))
    
    -- 设置当前节点
    state.current_node = node_id
    
    -- 获取节点文本内容（可能是函数或字符串）
    local node_text = node.text
    if type(node.text) == "function" then
        node_text = node.text(state)
        print("StoryEngine: 节点文本是函数，计算结果: " .. tostring(node_text))
    else
        print("StoryEngine: 节点文本是静态字符串: " .. tostring(node_text))
    end
    
    -- 初始化变量
    if node.vars then
        print("StoryEngine: 处理节点变量，共 " .. #node.vars .. " 个")
        for key, value in pairs(node.vars) do
            if type(value) == "function" then
                -- 如果是函数，计算新值
                local old_value = state.variables[key]
                state.variables[key] = value(state)
                print("StoryEngine: 变量 " .. key .. " 从 " .. tostring(old_value) .. " 更新为 " .. tostring(state.variables[key]))
            else
                -- 直接赋值
                state.variables[key] = value
                print("StoryEngine: 变量 " .. key .. " 设置为 " .. tostring(value))
            end
        end
    end
    
    -- 更新标题和内容显示
    local title_node = gui.get_node("title")
    local content_node = gui.get_node("content")
    
    if title_node then
        local title_text = node.title or "无标题"
        gui.set_text(title_node, title_text)
        print("StoryEngine: 设置标题: " .. title_text)
    else
        print("StoryEngine: 警告：找不到title节点")
    end
    
    if content_node then
        gui.set_text(content_node, node_text or "")
        print("StoryEngine: 设置内容: " .. tostring(node_text))
    else
        print("StoryEngine: 警告：找不到content节点")
    end
    
    -- 确保根节点可见
    local root_node = gui.get_node("root")
    if root_node then
        gui.set_enabled(root_node, true)
        print("StoryEngine: 已启用根节点")
    else
        print("StoryEngine: 警告：找不到root节点")
    end
    
    -- 获取可用选择
    local available_choices = M.get_available_choices(node)
    print("StoryEngine: 当前节点有 " .. #available_choices .. " 个可用选择")
    
    -- 检查是否有可用选择
    if #available_choices == 0 then
        print("StoryEngine: 没有可用选择，检查是否有自动跳转")
        -- 没有可用选择，检查是否有自动跳转
        if node.next then
            local next_node_id
            if type(node.next) == "function" then
                next_node_id = node.next(state)
            else
                next_node_id = node.next
            end
            if next_node_id then
                print("StoryEngine: 找到自动跳转，3秒后执行: " .. tostring(next_node_id))
                -- 延迟自动跳转，给玩家时间阅读
                timer.delay(3.0, false, function()
                    M.show_node(next_node_id)
                end)
            else
                print("StoryEngine: 没有找到自动跳转目标，显示游戏结束")
                -- 游戏结束
                M.show_game_over()
            end
        else
            print("StoryEngine: 没有自动跳转，显示游戏结束")
            -- 游戏结束
            M.show_game_over()
        end
    else
        print("StoryEngine: 有可用选择，更新按钮")
        -- 更新选择按钮
        M.update_choices_gui()
    end
    
    print("StoryEngine: ========== show_node 结束 ==========")
    return true
end

-- 更新选择按钮的GUI显示
function M.update_choices_gui()
    print("StoryEngine: ========== update_choices_gui 开始 ==========")
    
    -- 清空旧的选择按钮
    print("StoryEngine: 清空旧的选择按钮")
    for i = 1, 6 do
        local choice_node = gui.get_node("choice_" .. i)
        local choice_text_node = gui.get_node("choice_text_" .. i)
        
        if choice_node then
            gui.set_enabled(choice_node, false)
        end
        
        if choice_text_node then
            gui.set_enabled(choice_text_node, false)
            gui.set_text(choice_text_node, "")  -- 清空文字
        end
    end
    
    -- 获取当前节点的choices
    local current_node = state.nodes[state.current_node]
    if not current_node then
        print("StoryEngine: 错误：当前节点不存在 " .. tostring(state.current_node))
        print("StoryEngine: ========== update_choices_gui 结束（节点不存在） ==========")
        return
    end
    
    print("StoryEngine: 更新选择按钮，当前节点: " .. current_node.id)
    print("StoryEngine: 当前节点choices数量: " .. tostring(#current_node.choices))
    
    -- 遍历choices，设置按钮
    for i, choice in ipairs(current_node.choices) do
        if i <= 6 then  -- 最多6个按钮
            print("StoryEngine: 处理选择 " .. i .. ": " .. tostring(choice.text) .. "，跳转目标: " .. tostring(choice.next))
            
            local choice_node = gui.get_node("choice_" .. i)
            local choice_text_node = gui.get_node("choice_text_" .. i)
            
            if choice_node and choice_text_node then
                print("StoryEngine: 设置按钮 " .. i .. " 文字: " .. tostring(choice.text))
                
                -- 启用按钮节点
                gui.set_enabled(choice_node, true)
                
                -- 启用文字节点并设置可见
                gui.set_enabled(choice_text_node, true)
                
                -- 设置文字，确保使用字符串
                local button_text = tostring(choice.text or "未知选项")
                gui.set_text(choice_text_node, button_text)
                
                -- 确保文字节点可见
                gui.set_color(choice_text_node, vmath.vector4(1, 1, 1, 1))  -- 白色
                
                print("StoryEngine: 按钮 " .. i .. " 设置完成: " .. button_text)
            else
                if not choice_node then
                    print("StoryEngine: 错误：找不到choice_node " .. i)
                end
                if not choice_text_node then
                    print("StoryEngine: 错误：找不到choice_text_node " .. i)
                end
            end
        end
    end
    
    print("StoryEngine: 按钮GUI更新完成，当前节点 " .. current_node.id .. " 有 " .. #current_node.choices .. " 个选择")
    
    -- 向GUI脚本传递选择数据
    print("StoryEngine: 检查GUI脚本引用，state.gui_script存在: " .. tostring(state.gui_script ~= nil))
    
    if state.gui_script then
        local choices = M.get_available_choices(current_node)
        print("StoryEngine: 向GUI脚本传递 " .. #choices .. " 个可用选择")
        
        -- 使用消息传递方式调用GUI脚本的update_choice_buttons方法
        print("StoryEngine: 使用消息传递方式更新GUI选择按钮")
        msg.post(".", "update_choices", { choices = choices })
    else
        print("StoryEngine: 错误：GUI脚本引用不存在")
    end
    
    print("StoryEngine: ========== update_choices_gui 结束 ==========")
end

-- 显示游戏结束界面
function M.show_game_over()
    -- 可以在这里显示游戏结束界面
    -- 例如显示最终得分、结局类型等
    local ending = M.get_var("game.ending") or "normal"
    local score = M.get_var("game.score") or 0
    
    local title = "游戏结束"
    local content = string.format("结局类型: %s\n得分: %d", ending, score)
    
    gui.set_text(gui.get_node("title"), title)
    gui.set_text(gui.get_node("content"), content)
    
    -- 隐藏所有选择按钮
    for i = 1, 6 do
        local choice_node = gui.get_node("choice_" .. i)
        if choice_node then
            gui.set_enabled(choice_node, false)
        end
    end
end

-- 获取可用选择
function M.get_available_choices(node)
    if not node.choices then
        return {}
    end
    
    local available = {}
    for _, choice in ipairs(node.choices) do
        -- 检查条件（如果有的话）
        if not choice.condition or choice.condition(state) then
            table.insert(available, choice)
        end
    end
    
    return available
end

-- 处理玩家选择
function M.make_choice(choice_index)
    print("StoryEngine: ========== make_choice 开始 ==========")
    print("StoryEngine: 玩家选择索引: " .. tostring(choice_index))
    print("StoryEngine: 当前节点ID: " .. tostring(state.current_node))
    
    -- 打印所有可用选择供参考
    local node = state.nodes[state.current_node]
    if node and node.choices then
        print("StoryEngine: 当前节点 '" .. node.id .. "' 的所有原始选择:")
        for i, choice in ipairs(node.choices) do
            print("StoryEngine:   " .. i .. ": " .. tostring(choice.text) .. " -> " .. tostring(choice.next))
        end
    end
    
    local node = state.nodes[state.current_node]
    if not node then
        print("StoryEngine: 错误：当前节点不存在! 当前节点ID: " .. tostring(state.current_node))
        print("StoryEngine: 可用节点: " .. tostring(state.nodes and "有节点" or "无节点"))
        return
    end
    
    if not node.choices then
        print("StoryEngine: 错误：当前节点没有选择! 节点ID: " .. node.id)
        return
    end
    
    print("StoryEngine: 当前节点: " .. node.id .. "，有 " .. #node.choices .. " 个选择")
    
    local available_choices = M.get_available_choices(node)
    print("StoryEngine: 可用选择数量: " .. #available_choices)
    
    -- 打印可用选择详情
    print("StoryEngine: 可用选择列表:")
    for i, choice in ipairs(available_choices) do
        print("StoryEngine:   可用选择 " .. i .. ": " .. tostring(choice.text) .. " -> " .. tostring(choice.next))
    end
    
    if choice_index < 1 or choice_index > #available_choices then
        print("StoryEngine: 无效的选择! 索引: " .. choice_index .. ", 可用选择数量: " .. #available_choices)
        for i, choice in ipairs(available_choices) do
            print("StoryEngine: 可用选择 " .. i .. ": " .. tostring(choice.text))
        end
        return
    end
    
    local choice = available_choices[choice_index]
    print("StoryEngine: 选择内容: " .. tostring(choice.text))
    print("StoryEngine: 选择跳转目标: " .. tostring(choice.next))
    
    -- 处理跳转
    if choice.next then
        local next_node_id
        if type(choice.next) == "function" then
            next_node_id = choice.next(state)
            print("StoryEngine: 选择跳转是函数，执行结果: " .. tostring(next_node_id))
        else
            next_node_id = choice.next
            print("StoryEngine: 选择跳转是直接ID: " .. next_node_id)
        end
        
        if next_node_id then
            print("StoryEngine: 准备跳转到节点: " .. tostring(next_node_id))
            
            -- 检查目标节点是否存在
            if not state.nodes[next_node_id] then
                print("StoryEngine: 错误：目标节点不存在! 目标ID: " .. tostring(next_node_id))
                print("StoryEngine: 所有可用节点:")
                for node_id, _ in pairs(state.nodes) do
                    print("StoryEngine: - " .. node_id)
                end
                return
            end
            
            print("StoryEngine: 目标节点存在，开始跳转")
            state.current_node = next_node_id
            M.show_node(next_node_id)
            print("StoryEngine: ========== make_choice 结束 ==========")
        else
            print("StoryEngine: 错误：无法获取跳转目标ID")
        end
    else
        print("StoryEngine: 警告：当前选择没有跳转目标")
    end
end

-- 获取变量值（支持点号路径）
function M.get_var(path)
    local keys = {}
    for key in string.gmatch(path, "[^.]+") do
        table.insert(keys, key)
    end
    
    local value = state.variables
    for _, key in ipairs(keys) do
        if type(value) == "table" and value[key] ~= nil then
            value = value[key]
        else
            return nil
        end
    end
    
    return value
end

-- 设置变量值（支持点号路径）
function M.set_var(path, value)
    local keys = {}
    for key in string.gmatch(path, "[^.]+") do
        table.insert(keys, key)
    end
    
    local current = state.variables
    for i = 1, #keys - 1 do
        local key = keys[i]
        if not current[key] or type(current[key]) ~= "table" then
            current[key] = {}
        end
        current = current[key]
    end
    
    current[keys[#keys]] = value
end

-- 保存游戏
function M.save_game()
    local save_data = {
        current_node = state.current_node,
        variables = state.variables
    }
    
    -- 这里应该写入文件，简化处理
    print("游戏已保存到: " .. state.save_file)
    return save_data
end

-- 加载游戏
function M.load_game(save_data)
    if not save_data then
        print("无法加载存档")
        return false
    end
    
    state.variables = save_data.variables or {}
    state.current_node = save_data.current_node
    
    print("游戏已加载")
    M.show_node(state.current_node)
    return true
end

-- 获取当前节点ID
function M.get_current_node_id()
    return state.current_node
end

-- 获取所有变量
function M.get_all_variables()
    return state.variables
end

-- 获取所有节点
function M.get_all_nodes()
    return state.nodes
end

-- 获取当前GUI脚本引用
function M.get_gui_script()
    return state.gui_script
end

-- 导出模块
return M